using System;
using System.Globalization;
using System.Data;
using Microsoft.SharePoint;
using Microsoft.Office.Server.Diagnostics;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;
using System.Net;
using SharePointStu.SharePoint.Logging;

namespace Noftware.SPArchiveTweets.TweetTimer
{
    /// <summary>
    /// Worker class that represents the Archive Tweets Timer. 
    /// </summary>
    public class Worker : SPJobDefinition
    {
        /// <summary>
        /// Default constructor.
        /// </summary>
        public Worker() : base() { }

        /// <summary>
        /// Constructor to specify name of job and reference to owning web application.
        /// </summary>
        /// <param name="jobName">name of job</param>
        /// <param name="webApplication">owning web application</param>
        public Worker(string jobName, SPWebApplication webApplication)
            : base(jobName, webApplication, null, SPJobLockType.Job)
        { this.Title = JobTitle; }

        /// <summary>
        /// Name of the Timer job.
        /// </summary>
        public static readonly string JobTitle = "Archive Tweets Timer";

        /// <summary>
        /// Execute the job.
        /// </summary>
        /// <param name="targetInstanceId">Unique identifier that represents the job.</param>
        public override void Execute(Guid targetInstanceId)
        {
            this.UpdateProgress(0);
            Logger.LogInfoLocal(EventId.Information, CategoryId.None, string.Format("{0} job started.", JobTitle));

            // Get the URL from the farm settings
            string url = AppData.Local.Entries[AppData.SHAREPOINT_SITE_URL];
            if (string.IsNullOrEmpty(url) == true || url.ToLower() == "http://")
            {
                string error = string.Format("{0} has no source URL defined.", JobTitle);
                Logger.LogErrorLocal(EventId.Error, CategoryId.Error, ErrorLevel.Unexpected, error, null);
                throw new SPException(error);
            }
            else
            {
                Logger.LogInfoLocal(EventId.Information, CategoryId.None, string.Format("{0} is using defined URL {1}.", JobTitle, url));
                this.UpdateProgress(10);
            }

            try
            {
                // Twitter class (wraps REST)
                var list = new SPTweetList();
                this.UpdateProgress(15);

                // Create the lists to hold the accounts and tweet items
                using (var site = new SPSite(url))
                {
                    using (var web = site.RootWeb)
                    {
                        try
                        {
                            bool originalValue = web.AllowUnsafeUpdates;
                            web.AllowUnsafeUpdates = true;

                            // Create SP Archive Tweet lists
                            try
                            {
                                list.CreateListsIfNotPresent(web);
                                this.UpdateProgress(50);

                                // Populate SP Archive Tweet lists
                                list.ArchiveTweets(web);
                                this.UpdateProgress(100);
                            }
                            catch (Exception ex)
                            {
                                Logger.LogErrorLocal(EventId.Error, CategoryId.Error, ErrorLevel.Unexpected, "A fatal error occurred in creating the twitter lists.", ex);
                                throw;
                            }

                            web.AllowUnsafeUpdates = originalValue;
                        }
                        catch (Exception ex)
                        {
                            Logger.LogErrorLocal(EventId.Error, CategoryId.Error, ErrorLevel.Unexpected, "A fatal error occurred in creating the twitter lists.", ex);
                            throw;
                        }
                    };
                };

                Logger.LogInfoLocal(EventId.Information, CategoryId.None, string.Format("{0} job completed.", JobTitle));
            }
            catch (Exception ex)
            {
                Logger.LogErrorLocal(EventId.Error, CategoryId.Error, ErrorLevel.Unexpected, string.Format("{0} error: {1}.", JobTitle, ex.Message), ex);
                throw ex;
            }
        }
    }
}
